﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Runtime.CompilerServices;
using System.Text;
using System.Threading;
using System.Threading.Tasks;

namespace SemenQuest
{
    public static class StatisticsController
    {
        private static Int32 _EggsSpawned;
        private static Int32 _EggsImpregnated;
        private static Int32 _EggsDied;
        private static Int32 _EggsUnknown;
        private static Int32 _SemenSpawned;
        private static Int32 _SemenImpregnated;
        private static Int32 _SemenDied;
        private static Int32 _SemenUnknown;

        public static Boolean Running { get; private set; }

        public static Int32 EggsSpawned { get { return _EggsSpawned; } }
        public static Int32 EggsImpregnated { get { return _EggsImpregnated; } }
        public static Int32 EggsDied { get { return _EggsDied; } }
        public static Int32 EggsUnknown { get { return _EggsUnknown; } }
        public static Int32 SemenSpawned { get { return _SemenSpawned; } }
        public static Int32 SemenImpregnated { get { return _SemenImpregnated; } }
        public static Int32 SemenDied { get { return _SemenDied; } }
        public static Int32 SemenUnknown { get { return _SemenUnknown; } }

        [MethodImpl(MethodImplOptions.Synchronized)]
        public static void ResetStatistics()
        {
            if (!Running)
                throw new InvalidOperationException("Controller not initialized");

            _SemenSpawned = 0;
            _EggsSpawned = 0;
            _EggsImpregnated = 0;
            _EggsDied = 0;
            _SemenDied = 0;
            _SemenImpregnated = 0;
        }

        [MethodImpl(MethodImplOptions.Synchronized)]
        public static void Initialize()
        {
            if (!Running)
            {
                AgentController.AgentStateChanged += AgentController_AgentStateChanged;
                Running = true;
            }
        }

        private static void AgentController_AgentStateChanged(Models.Agent agent, AgentController.AgentEventArgs e)
        {
            ThreadPool.QueueUserWorkItem(new WaitCallback(UpdateStatictics), new Object[] { agent, e });
        }

        [MethodImpl(MethodImplOptions.Synchronized)]
        private static void UpdateStatictics(Object state)
        {
            var agent = (Models.Agent)((Object[])state)[0];
            var e = (AgentController.AgentEventArgs)((Object[])state)[1];

            switch (e.AdditionalInfo)
            {
                case AgentController.AgentEventArgs.AdditionalInfos.Unknown:
                    switch (agent.AgentType)
                    {
                        case SemenQuest.Models.Agent.AgentTypes.Egg:
                            _EggsUnknown++;
                            break;
                        case SemenQuest.Models.Agent.AgentTypes.Semen:
                            _SemenUnknown++;
                            break;
                        default:
                            break;
                    }
                    break;



                case AgentController.AgentEventArgs.AdditionalInfos.Spawned:
                    switch (agent.AgentType)
                    {
                        case SemenQuest.Models.Agent.AgentTypes.Egg:
                            _EggsSpawned++;
                            break;
                        case SemenQuest.Models.Agent.AgentTypes.Semen:
                            _SemenSpawned++;
                            break;
                        default:
                            break;
                    }
                    break;



                case AgentController.AgentEventArgs.AdditionalInfos.WonTheLottery:
                    switch (agent.AgentType)
                    {
                        case SemenQuest.Models.Agent.AgentTypes.Egg:
                            _EggsImpregnated++;
                            break;
                        case SemenQuest.Models.Agent.AgentTypes.Semen:
                            _SemenImpregnated++;
                            break;
                        default:
                            break;
                    }
                    break;



                case AgentController.AgentEventArgs.AdditionalInfos.AgentControllerKill:
                case AgentController.AgentEventArgs.AdditionalInfos.LifeTimeEnded:
                    switch (agent.AgentType)
                    {
                        case SemenQuest.Models.Agent.AgentTypes.Egg:
                            _EggsDied++;
                            break;
                        case SemenQuest.Models.Agent.AgentTypes.Semen:
                            _SemenDied++;
                            break;
                        default:
                            break;
                    }
                    break;

                default: break;
            }
        }
    }
}
